﻿using System;
using System.Reflection;
using System.Windows.Markup;

namespace XtremeMvvm
{
    public class GetDelegate : MvvmResolver<IXtremeMvvmViewModel>
    {
        private string function;

        public GetDelegate(string name)
        {
            function = name.Trim();
        }

        public override object ProvideValue(IServiceProvider serviceProvider)
        {
            MethodInfo methodInfo = ConcreteImplementation.GetType().GetMethod(function);
            if (methodInfo == null)
            {
                throw new InvalidOperationException(String.Format("Could not find function with name: {0}", function));
            }

            ParameterInfo[] pi = methodInfo.GetParameters();
            if (pi.Length == 0) return methodInfo.Invoke(ConcreteImplementation, null);
            if (pi.Length != 2)
            {
                throw new InvalidOperationException("Invalid delegate creation attempt!");
            }

            IProvideValueTarget targetProvider = serviceProvider.GetService(typeof(IProvideValueTarget)) as IProvideValueTarget;
            EventInfo targetEvent = targetProvider.TargetProperty as EventInfo;
            if (targetEvent == null)
            {
                return null; //Should never hit this.
            }
            Type handler = targetEvent.GetAddMethod().GetParameters()[0].ParameterType;

            try
            {
                return Delegate.CreateDelegate(handler, ConcreteImplementation, methodInfo);
            }
            catch
            {
                throw new InvalidOperationException(String.Format("Could not create a delegate for function {0} with handler: {1}", function, handler.FullName));
            }
        }
    }
}
